home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / cli / mcomms_1_4.lha / Src / clickstart.c < prev    next >
C/C++ Source or Header  |  1995-08-31  |  9KB  |  306 lines

  1. /*
  2. **    clickstart.c - enable/disable features of AmigaDOS
  3. **    Copyright ⌐ 1994-95 Michael Letowski
  4. */
  5.  
  6. #define __USE_SYSBASE
  7. #define ECS_SPECIFIC                                                        /* Enable hardware */
  8.  
  9. #include <exec/types.h>
  10. #include <exec/execbase.h>
  11. #include <dos/rdargs.h>
  12. #include <dos/var.h>
  13. #include <devices/trackdisk.h>
  14. #include <graphics/gfxbase.h>
  15. #include <hardware/custom.h>
  16. #include <support/types.h>
  17. #include <support/exec.h>
  18. #include <support/dos.h>
  19.  
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22. #include <proto/intuition.h>
  23.  
  24. #include "clickstart.rev.h"
  25.  
  26.  
  27. #define DOS_NAME        "dos.library"
  28. #define DOS_VERN        37L
  29. #define GFX_NAME        "graphics.library"
  30. #define GFX_VERN        39L
  31. #define INT_NAME        "intuition.library"
  32. #define INT_VERN        0L
  33. #define TRACK_NAME    "trackdisk.device"
  34.  
  35. /* Args template */
  36. #define TEMPLATE        "CLICK/S,NOCLICK/S,STAR/S,NOSTAR/S,"\
  37.                                         "PIPE/K,NOPIPE/S,MULTI/K,NOMULTI/S,"\
  38.                                         "BORBLANK/S,NOBORBLANK/S,BORSPRITES/S,NOBORSPRITES/S,"\
  39.                                         "ALERT/K/N,RETRY/K/N,QUANTUM/K/N,QUIET/S"
  40.  
  41. /* Info message */
  42. #define MSG_STATUS    "System state:\n"\
  43.                                         "\tClick is %s\n"\
  44.                                         "\tStar is %s\n"\
  45.                                         "\tPipe char is %s\n"\
  46.                                         "\tMulti command char is %s\n"\
  47.                                         "\tBorder blank is %s\n"\
  48.                                         "\tBorder sprites are %s\n"\
  49.                                         "\tAlert lasts %ld frame%s\n"\
  50.                                         "\tNumber of retries is %ld\n"\
  51.                                         "\tDispatch quantum is %ld frame%s\n"
  52.  
  53. /* Pipe enable/disable */
  54. #define PIPE_VAR_NAME        "_pchar"
  55.  
  56. /* Multi command enable/disable */
  57. #define MULTI_VAR_NAME    "_mchar"
  58.  
  59. #define VAR_LEN                    1
  60. #define VAR_FLAGS                (LV_VAR | GVF_LOCAL_ONLY)
  61. #define VAR_SIZE                (VAR_LEN+3)
  62.  
  63. /* Default pipe and multi characters */
  64. #define DEF_PIPE                "|"
  65. #define DEF_MULTI                "\\"
  66.  
  67. /* On/off texts */
  68. #define ON                            "ON"
  69. #define OFF                            "OFF"
  70. #define UNKNOWN                    "?"
  71.  
  72. /* Ranges */
  73. #define MIN_RETRY                0
  74. #define MAX_RETRY                255
  75. #define MIN_ALERT                0
  76. #define MAX_ALERT                0x7FFFFFFF
  77. #define MIN_QUANT                1
  78. #define MAX_QUANT                65535
  79.  
  80. #define PStr(arg,def)        (*(arg)=='\0' ? (def) : (arg))
  81.  
  82. STATIC CONST TEXT VersionString[]=
  83.     VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
  84.  
  85. struct Options
  86. {
  87.     LONG   opt_Click;                                                            /* C=CLICK/S */
  88.     LONG   opt_NoClick;                                                        /* NC=NOCLICK/S */
  89.     LONG   opt_Star;                                                            /* S=STAR/S */
  90.     LONG   opt_NoStar;                                                        /* NS=NOSTAR/S */
  91.     STRPTR opt_Pipe;                                                            /* P=PIPE/K */
  92.     LONG   opt_NoPipe;                                                        /* NP=NOPIPE/S */
  93.     STRPTR opt_Multi;                                                            /* M=MULTI/S */
  94.     LONG   opt_NoMulti;                                                        /* NM=NOMULTI/S */
  95.     LONG   opt_Blank;                                                            /* BB=BORBLANK/S */
  96.     LONG   opt_NoBlank;                                                        /* NBB=NOBORBLANK/S */
  97.     LONG   opt_Sprites;                                                        /* BS=BORSPRITES */
  98.     LONG   opt_NoSprites;                                                    /* NBS=NOBORSPRITES */
  99.     LONG  *opt_Alert;                                                            /* A=ALERT/K/N */
  100.     LONG  *opt_Retry;                                                            /* R=RETRY/K/N */
  101.     LONG  *opt_Quant;                                                            /* Q=QUANTUM/K/N */
  102.     LONG   opt_Quiet;                                                            /* QUIET/S */
  103. };    /* Options */
  104.  
  105. struct States
  106. {
  107.     STRPTR state_Click;
  108.     STRPTR state_Star;
  109.     STRPTR state_Pipe;
  110.     STRPTR state_Multi;
  111.     STRPTR state_Blank;
  112.     STRPTR state_Sprites;
  113.     LONG   state_Alert;
  114.     STRPTR state_AlertS;
  115.     LONG   state_Retry;
  116.     LONG   state_Quant;
  117.     STRPTR state_QuantS;
  118. };    /* States */
  119.  
  120. STATIC VOID HandleTrackDisk(struct Options *opts, struct States *stat, LONG *error);
  121. STATIC VOID HandleVar(STRPTR varName, STRPTR varVal, STRPTR defVal, LONG off,
  122.                                             LONG *error, STRPTR *result, struct DosLibrary *DOSBase);
  123. STATIC VOID HandleBorder(struct Options *opts, struct States *stat, LONG *error,
  124.                                                     struct DosLibrary *DOSBase);
  125.  
  126. LONG ClickStart(VOID)
  127. {
  128.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  129.     struct DosLibrary *DOSBase;
  130.  
  131.     CHAR PipeVal[VAR_SIZE],MultiVal[VAR_SIZE];
  132.     struct Options Opts;
  133.     struct States Stat;
  134.     struct RDArgs *Args;
  135.     LONG *DOSFlags,RC=RETURN_FAIL;
  136.  
  137.     /* Open DOS */
  138.     unless(DOSBase=(struct DosLibrary *)OpenLibrary(DOS_NAME,DOS_VERN))
  139.         throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY), NO_DOS);
  140.  
  141.     /* Read arguments */
  142.     clear(&Opts);                                                            /* Clear out buffer */
  143.     unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
  144.         throw2(PrintFault(IoErr(),PROG_NAME),    NO_ARGS);
  145.     /* Check args */
  146.     if(Opts.opt_Click && Opts.opt_NoClick || Opts.opt_Star && Opts.opt_NoStar ||
  147.             Opts.opt_Pipe && Opts.opt_NoPipe || Opts.opt_Multi && Opts.opt_NoMulti ||
  148.       Opts.opt_Blank && Opts.opt_NoBlank || Opts.opt_Sprites && Opts.opt_NoSprites)
  149.         throw2(CauseIoErr(ERROR_TOO_MANY_ARGS,PROG_NAME),    BAD_ARGS);
  150.     /* Make values legal*/
  151.     if(Opts.opt_Alert)    *Opts.opt_Alert=clamp(*Opts.opt_Alert,MIN_ALERT,MAX_ALERT);
  152.     if(Opts.opt_Retry)    *Opts.opt_Retry=clamp(*Opts.opt_Retry,MIN_RETRY,MAX_RETRY);
  153.     if(Opts.opt_Quant)    *Opts.opt_Quant=clamp(*Opts.opt_Quant,MIN_QUANT,MAX_QUANT);
  154.  
  155.     RC=RETURN_ERROR;                                                    /* Working a bit */
  156.  
  157.     /* Handle clicking */
  158.     HandleTrackDisk(&Opts,&Stat,&RC);
  159.  
  160.     /* Wildstar */
  161.     DOSFlags=&DOSBase->dl_Root->rn_Flags;
  162.     if(Opts.opt_Star)        fset(*DOSFlags,RNF_WILDSTAR);
  163.     if(Opts.opt_NoStar)    fclr(*DOSFlags,RNF_WILDSTAR);
  164.     Stat.state_Star=ftst(*DOSFlags,RNF_WILDSTAR) ? ON : OFF;
  165.  
  166.     /* Piping */
  167.     Stat.state_Pipe=PipeVal;
  168.     HandleVar(PIPE_VAR_NAME,Opts.opt_Pipe,DEF_PIPE,
  169.                         Opts.opt_NoPipe,&RC,&Stat.state_Pipe,DOSBase);
  170.  
  171.     /* Multi command execution */
  172.     Stat.state_Multi=MultiVal;
  173.     HandleVar(MULTI_VAR_NAME,Opts.opt_Multi,DEF_MULTI,
  174.                         Opts.opt_NoMulti,&RC,&Stat.state_Multi,DOSBase);
  175.  
  176.     /* Border stuff */
  177.     HandleBorder(&Opts,&Stat,&RC,DOSBase);
  178.  
  179.     /* Alerts timing */
  180.     if(Opts.opt_Alert)    SysBase->LastAlert[3]=*Opts.opt_Alert;
  181.     Stat.state_Alert=SysBase->LastAlert[3];
  182.     Stat.state_AlertS=(Stat.state_Alert==1) ? NULL : "s";
  183.  
  184.     /* Quantum */
  185.     if(Opts.opt_Quant)    SysBase->Quantum=*Opts.opt_Quant;
  186.     Stat.state_Quant=SysBase->Quantum;
  187.     Stat.state_QuantS=(Stat.state_Quant==1) ? NULL : "s";
  188.  
  189.     unless(Opts.opt_Quiet)
  190.         VPrintf(MSG_STATUS,(LONG *)&Stat);
  191.  
  192.     catch(BAD_ARGS,    );
  193.     catch(NO_ARGS,    FreeArgs(Args));
  194.     catch(NO_DOS,        CloseLibrary((struct Library *)DOSBase));
  195.     return(RC);
  196. }    /* ClickStart */
  197.  
  198. STATIC VOID HandleTrackDisk(struct Options *opts, struct States *stat, LONG *error)
  199. {
  200.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  201.  
  202.     struct MsgPort *Port;
  203.     struct IOExtTD *IO;
  204.     struct TDU_PublicUnit *TDUUnit;
  205.     ULONG Unit;
  206.  
  207.     stat->state_Click=UNKNOWN;                                        /* We don't know yet */
  208.  
  209.     try(Port=CreateMsgPort(),                                                            NO_PORT);
  210.     try(IO=CreateIORequest(Port,sizeof(struct IOExtTD)),    NO_IO)
  211.  
  212.     *error=RETURN_OK;                                                    /* Everything OK so far */
  213.     for(Unit=0; Unit<4; Unit++)                                /* For each drive */
  214.         if(OpenDevice(TRACK_NAME,Unit,(struct IORequest *)IO,0)==0)
  215.         {
  216.             TDUUnit=(struct TDU_PublicUnit *)IO->iotd_Req.io_Unit;
  217.             /* Disable/enable clicking */
  218.             if(opts->opt_Click)        fclr(TDUUnit->tdu_PubFlags,TDPF_NOCLICK);
  219.             if(opts->opt_NoClick)    fset(TDUUnit->tdu_PubFlags,TDPF_NOCLICK);
  220.             stat->state_Click=ftst(TDUUnit->tdu_PubFlags,TDPF_NOCLICK) ? OFF : ON;
  221.  
  222.             /* Change retry count */
  223.             if(opts->opt_Retry)        TDUUnit->tdu_RetryCnt=*opts->opt_Retry;
  224.             stat->state_Retry=TDUUnit->tdu_RetryCnt;
  225.  
  226.             /* Clean up */
  227.             CloseDevice((struct IORequest *)IO);
  228.         }
  229.  
  230.     catch(NO_PORT,    DeleteMsgPort(Port));
  231.     catch(NO_IO,        DeleteIORequest(IO));
  232. }    /* HandleTrackDisk */
  233.  
  234. STATIC VOID HandleVar(STRPTR varName, STRPTR varVal, STRPTR defVal, LONG off,
  235.                                             LONG *error, STRPTR *result, struct DosLibrary *DOSBase)
  236. {
  237.     STRPTR State=*result;
  238.     struct LocalVar *Var;
  239.  
  240.     if(varVal)
  241.         unless(SetVar(varName,PStr(varVal,defVal),VAR_LEN,VAR_FLAGS))
  242.         {
  243.             PrintFault(IoErr(),PROG_NAME);
  244.             *error=RETURN_ERROR;
  245.         }
  246.     if(off)
  247.         unless(DeleteVar(varName,VAR_FLAGS))
  248.         {
  249.             PrintFault(IoErr(),PROG_NAME);
  250.             *error=RETURN_ERROR;
  251.         }
  252.     if(Var=FindVar(varName,VAR_FLAGS))                        /* Could find var */
  253.     {
  254.         State[0]='\'';                                                            /* Store its contents */
  255.         State[1]=*(Var->lv_Value);
  256.         State[2]='\'';
  257.         State[3]='\0';
  258.     }
  259.     else                                                                                    /* Var nor found */
  260.         *result=OFF;                                                                /* So it's off */
  261. }    /* HandleVar */
  262.  
  263. STATIC VOID HandleBorder(struct Options *opts, struct States *stat, LONG *error,
  264.                                                     struct DosLibrary *DOSBase)
  265. {
  266.     struct ExecBase *SysBase=*((struct ExecBase **)4);
  267.     struct GfxBase *GfxBase;
  268.     struct IntuitionBase *IntuitionBase;
  269.  
  270.     UBYTE BP3Bits;
  271.  
  272.     stat->state_Sprites=UNKNOWN;
  273.     stat->state_Blank=UNKNOWN;
  274.  
  275.     if(GfxBase=(struct GfxBase *)OpenLibrary(GFX_NAME,GFX_VERN))
  276.     {
  277.         BP3Bits=GfxBase->BP3Bits;                                        /* Remember flags */
  278.  
  279.         /* Sprites on border */
  280.         if(opts->opt_Sprites)            fset(GfxBase->BP3Bits,BPLCON3_EXTBLKZD);
  281.         if(opts->opt_NoSprites)        fclr(GfxBase->BP3Bits,BPLCON3_EXTBLKZD);
  282.         stat->state_Sprites=ftst(GfxBase->BP3Bits,BPLCON3_EXTBLKZD) ? ON : OFF;
  283.  
  284.         /* Blank border */
  285.         if(opts->opt_Blank)                fset(GfxBase->BP3Bits,BPLCON3_BRDNBLNK);
  286.         if(opts->opt_NoBlank)            fclr(GfxBase->BP3Bits,BPLCON3_BRDNBLNK);
  287.         stat->state_Blank=ftst(GfxBase->BP3Bits,BPLCON3_BRDNBLNK) ? ON : OFF;
  288.  
  289.         if(BP3Bits!=GfxBase->BP3Bits)                                /* Changed something */
  290.             if(IntuitionBase=(struct IntuitionBase *)OpenLibrary(INT_NAME,INT_VERN))
  291.             {
  292.                 RemakeDisplay();                                                /* Make changes visible */
  293.                 CloseLibrary((struct Library *)IntuitionBase);
  294.             }
  295.             else                                                                            /* Unable to open intuition */
  296.                 *error=RETURN_WARN;                                            /* Just warning */
  297.  
  298.         CloseLibrary((struct Library *)GfxBase);        /* Close graphics */
  299.     }
  300.     else                                                                                    /* No graphics */
  301.     {
  302.         *error=RETURN_ERROR;                                                /* An error */
  303.         CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,PROG_NAME);
  304.     }
  305. }    /* HandleBorder */
  306.